package core

import (
	"bytes"
	"github.com/360EntSecGroup-Skylar/excelize"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"sync"

	"fmt"
	"strconv"
	"time"
)

const LuaFileNameFix = "Data"
const LuaIdxName = "idx"

type excelFileInfo struct {
	fileName string
	path     string
}

// 开始执行
func StartProc(config *Config) {
	exportConfigs := config.getEnableConfig()
	path := config.XlsxSourcePath
	curProcTypes := ""
	for k := range exportConfigs {
		curProcTypes += k + ","
	}
	fmt.Println("解析导出类型:", curProcTypes)
	fmt.Println("开始处理excel:", path)

	for _, v := range exportConfigs {
		e := CleanDir(v.SavePath)
		if e != nil {
			log.Fatal(e)
		}
		e = os.MkdirAll(v.SavePath, os.ModePerm)
		if e != nil {
			log.Fatal(e)
		}
		fmt.Println("clean dir[" + v.SavePath + "] suc")
	}
	var fileInfos []*excelFileInfo
	err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if info == nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		suffix := ".xlsx"
		fileName := info.Name()

		var isHiddenOrTmpFile = strings.HasPrefix(fileName, ".") || strings.HasPrefix(fileName, "~")
		if !isHiddenOrTmpFile && strings.HasSuffix(path, suffix) {
			fileName = fileName[0 : len(fileName)-len(suffix)]
			infos := new(excelFileInfo)
			infos.path = path
			infos.fileName = fileName
			fileInfos = append(fileInfos, infos)
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	group := sync.WaitGroup{}
	group.Add(len(fileInfos))
	for k, v := range fileInfos {
		go func(idx int, val *excelFileInfo, group *sync.WaitGroup) {
			defer func(now time.Time) {
				fmt.Printf("[%20s]\t export suc spend:[%3s] ms\n", val.fileName, strconv.FormatInt(time.Since(now).Nanoseconds()/1000000, 10))
			}(time.Now())
			buildFile(val.path, val.fileName, exportConfigs)

			group.Done()

		}(k, v, &group)
	}
	group.Wait()
	fmt.Println(" finish")
}

func buildFile(path string, fileName string, configs map[string]*ExportConfig) {
	file, e := excelize.OpenFile(path)
	if e != nil {
		println(e)
	} else {
		name := file.GetSheetName(1)

		compile, _ := regexp.Compile("\n|\r|\n\r")
		for _, config := range configs {
			builder := config.DefConfig.Builder
			var headInfo *HeadInfo
			var exportString = new(bytes.Buffer)
			var saveFileName = builder.GetSaveFileName(fileName)

			for rowNum, row := range file.GetRows(name) {
				for k, v := range row {
					row[k] = strings.TrimSpace(compile.ReplaceAllString(v, ""))
				}
				if 0 == rowNum {
					// head info
					headInfo = builder.BuildHeadInfo(row, config.DefConfig.HeadFix)

					header := config.Header
					if header != "" {
						header = strings.Replace(header, "{dataName}", saveFileName, -1)
						exportString.WriteString(header)
						exportString.WriteString("\n")
					}
					builder.BuildHeadLine(exportString, saveFileName, headInfo)
				} else {
					if row[0] == "" {
						continue
					}
					// buildContent
					id := builder.GetID(row, headInfo)
					builder.BuildLine(exportString, headInfo, id, row)
				}
			}
			builder.BuildEnd(exportString, headInfo)
			saveFile(config, saveFileName, exportString)
		}
	}
}

func logError(er error) {
	if er != nil {
		log.Fatal(er)
	}
}
